<template>
  <div>
    <p class=" text-forestgreen">点击节点显示节点信息</p>
    <p>运行模式: <b>{{ connInfo.redisRunMode }}</b></p>
    <el-row>
      <el-col :span="8">
        <el-tree :data="connInfo.masterNodes"
                 :expand-on-click-node="false"
                 :default-expand-all="true"
                 :props="defaultProps"
                 node-key="id"
                 @node-click="clickNode">
          <div slot-scope="{ node, data }" class="custom-tree-node">
            <b class="margin-right">{{ data.role }}</b>
            <span v-if="data.hostAndPort">{{ data.hostAndPort.host }}:{{ data.hostAndPort.port }}</span>
            <span v-if="connInfo.redisRunMode === 'cluster' && data.role === 'master' ">
              <!-- 集群模式显示槽位信息 -->
              {{ data.slotStart }} - {{ data.slotEnd }}
            </span>
          </div>
        </el-tree>
      </el-col>
      <el-col v-show="nodeInfoTabs.nodeId" :span="15" class="margin-left">
        <div>当前节点:
          <span v-if="nodeInfoTabs.node.hostAndPort">{{ nodeInfoTabs.node.hostAndPort.host }}:{{ nodeInfoTabs.node.hostAndPort.port }}</span>
          <span v-else>{{ nodeInfoTabs.nodeId }}</span>
        </div>
        <el-tabs class="" :active-name="nodeInfoTabs.activeTabName" @tab-click="switchNodeInfoTab">
          <el-tab-pane name="server" :label="nodeInfoTabs.server.title">
            <el-descriptions class="margin-top" title="服务相关信息总览" :column="2"  border>
              <el-descriptions-item label="version">{{nodeInfoTabs.server.data.version}}</el-descriptions-item>
              <el-descriptions-item label="mode">{{nodeInfoTabs.server.data.mode}}</el-descriptions-item>
              <el-descriptions-item label="os">{{nodeInfoTabs.server.data.os}}</el-descriptions-item>
              <el-descriptions-item label="archBits">{{nodeInfoTabs.server.data.archBits}}</el-descriptions-item>
              <el-descriptions-item label="pid">{{nodeInfoTabs.server.data.pid}}</el-descriptions-item>
              <el-descriptions-item label="port">{{nodeInfoTabs.server.data.port}}</el-descriptions-item>
              <el-descriptions-item label="upTime">{{formatDuration(nodeInfoTabs.server.data.upTime * 1000)}}</el-descriptions-item>
            </el-descriptions>
          </el-tab-pane>
          <el-tab-pane name="dbSize" :label="nodeInfoTabs.dbSize.title">
            <el-table
              :data="nodeInfoTabs.dbSize.data"
              border
              stripe
              height="600"
              size="mini"
            >
              <el-table-column
                prop="db"
                label="db"
                width="70"
              />
              <el-table-column
                prop="size"
                label="size"
                width="100"
              />
            </el-table>
          </el-tab-pane>
          <el-tab-pane name="clients" :label="nodeInfoTabs.clients.title">
            <span style="display: block" class="margin-bottom"><b>总连接数: </b>{{ nodeInfoTabs.clients.data.length }}</span>
            <el-table
              :data="clients"
              border
              stripe
              style="width: 100%"
              size="mini"
              height="400"
            >
              <el-table-column
                prop="id"
                label="id"
              />
              <el-table-column
                label="client"
                sortable
                width="150"
              >
                <template slot-scope="scope">
                  <span>{{ scope.row.connect.host + ':' + scope.row.connect.port }}</span>
                </template>
              </el-table-column>
              <el-table-column
                prop="age"
                label="age"
                sortable
              />
              <el-table-column
                prop="idle"
                label="idle"
                sortable
              />
              <el-table-column
                prop="cmd"
                label="cmd"
                sortable
              />
              <el-table-column
                fixed="right"
                label="操作"
                width="150"
              >
                <template slot-scope="scope">
                  <el-button type="text" class="text-danger" size="small" @click="killClient(scope.row.connect,nodeInfoTabs.nodeId)">kill</el-button>
                </template>
              </el-table-column>
            </el-table>
            <!--分页组件-->
            <el-pagination
              :current-page="nodeInfoTabs.clients.currentPage"
              :page-size="nodeInfoTabs.clients.pageSize"
              layout="total, sizes, prev, pager, next"
              :total="nodeInfoTabs.clients.data.length"
              @size-change="handleNodeInfoTabSizeChange"
              @current-change="handleNodeInfoTabCurrentChange"
            />
          </el-tab-pane>
          <el-tab-pane name="memory" :label="nodeInfoTabs.memory.title">
<!--            <ul class="memory-show" style="">-->
<!--              <li><label >rss:</label> {{ formatSizeHuman(nodeInfoTabs.memory.data.rss) }}</li>-->
<!--              <li><label >max:</label> {{ formatSizeHuman(nodeInfoTabs.memory.data.max) }}</li>-->
<!--              <li><label >system:</label> {{ formatSizeHuman(nodeInfoTabs.memory.data.system) }}</li>-->
<!--              <li><label >lua:</label> {{ formatSizeHuman(nodeInfoTabs.memory.data.lua) }}</li>-->
<!--              <li><label >policy:</label> {{ nodeInfoTabs.memory.data.policy }}</li>-->
<!--              <li><label >dbSize: </label> {{ nodeInfoTabs.memory.data.dbSize }}</li>-->
<!--            </ul>-->
            <el-descriptions class="margin-top" title="内存相关数据" :column="2"  border>
              <el-descriptions-item label="rss">{{ formatSizeHuman(nodeInfoTabs.memory.data.rss) }}</el-descriptions-item>
              <el-descriptions-item label="max">{{ formatSizeHuman(nodeInfoTabs.memory.data.max) }}</el-descriptions-item>
              <el-descriptions-item label="system">{{ formatSizeHuman(nodeInfoTabs.memory.data.system) }}</el-descriptions-item>
              <el-descriptions-item label="lua">{{ formatSizeHuman(nodeInfoTabs.memory.data.lua) }}</el-descriptions-item>
              <el-descriptions-item label="policy">{{ nodeInfoTabs.memory.data.policy }}</el-descriptions-item>
              <el-descriptions-item label="dbSize">{{ formatSizeHuman(nodeInfoTabs.memory.data.dbSize) }}</el-descriptions-item>
            </el-descriptions>
          </el-tab-pane>
          <el-tab-pane name="slowlogs" :label="nodeInfoTabs.slowlogs.title">
            <span style="display: block" class="margin-bottom"><b>慢查询数量:</b>{{ nodeInfoTabs.slowlogs.data.length }}</span>
            <el-table
              :data="slowlogs"
              border
              stripe
              style="width: 100%"
              size="mini"
              height="400"
            >
              <el-table-column
                prop="id"
                label="id"
                width="80"
              />

              <el-table-column
                label="timeStamp"
                sortable
                width="150"
              >
                <template slot-scope="scope">
                  <span>{{ parseTime(scope.row.timeStamp) }}</span>
                </template>
              </el-table-column>

              <el-table-column
                prop="executionTime"
                label="executionTime"
                sortable
                width="140"
              />

              <el-table-column
                label="args"
              >
                <template slot-scope="scope">
                  <span>{{ scope.row.args ? scope.row.args.join(' '): '' }}</span>
                </template>
              </el-table-column>
              <!--              <el-table-column-->
              <!--                fixed="right"-->
              <!--                label="操作"-->
              <!--                width="150"-->
              <!--              >-->
              <!--                <template slot-scope="scope">-->
              <!--                </template>-->
              <!--              </el-table-column>-->
            </el-table>
            <!--分页组件-->
            <el-pagination
              :current-page="nodeInfoTabs.slowlogs.input.currentPage"
              :page-size="nodeInfoTabs.slowlogs.input.pageSize"
              layout="total, sizes, prev, pager, next"
              :total="nodeInfoTabs.slowlogs.data.length"
              @size-change="handleNodeInfoTabSizeChange"
              @current-change="handleNodeInfoTabCurrentChange"
            />
          </el-tab-pane>
        </el-tabs>
      </el-col>
    </el-row>

  </div>
</template>

<script>
import redis from '@/api/redis'
import { formatSizeHuman, parseTime,formatDuration } from '@/utils'

export default {
  name: 'Dashboard',
  props: {
    connParam: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      defaultProps: {
        children: 'slaveNodes',
        label: 'label'
      },
      connInfo: {
        redisRunMode: null,
        masterNodes: []
      },
      nodeInfoTabs: {
        activeTabName: 'server',
        loading: false,
        nodeId: null,
        node: {},
        server: {
          title: '服务总览',
          data: {}
        },
        dbSize: {
          title: '数据量',
          data: []
        },
        clients: {
          title: '客户端连接',
          data: [],
          input: {
            currentPage: 1,
            pageSize: 20
          }
        },
        memory: {
          title: '内存占用',
          data: {}
        },
        slowlogs: {
          title: '慢查询',
          data: [],
          input: {
            currentPage: 1,
            pageSize: 20
          }
        }
      }
    }
  },
  computed: {
    clients() {
      const clients = this.nodeInfoTabs.clients
      if (!clients.data) {
        return []
      }
      const start = (clients.input.currentPage - 1) * clients.input.pageSize
      let end = clients.input.currentPage * clients.input.pageSize
      if (end > clients.data.length) {
        end = clients.data.length
      }
      return clients.data.slice(start, end)
    },
    slowlogs() {
      const slowlogs = this.nodeInfoTabs.slowlogs
      if (!slowlogs.data) {
        return []
      }
      const start = (slowlogs.input.currentPage - 1) * slowlogs.input.pageSize
      let end = slowlogs.input.currentPage * slowlogs.input.pageSize
      if (end > slowlogs.data.length) {
        end = slowlogs.data.length
      }
      return slowlogs.data.slice(start, end)
    }
  },
  mounted() {

  },
  methods: {
    init() {
      this.loadRedisConnInfo()
    },
    formatSizeHuman, parseTime,formatDuration,
    clickNode(data, node, el) {
      this.loadNodeInfo(data)
    },
    loadNodeInfo(node) {
      this.nodeInfoTabs.nodeId = node.id
      this.nodeInfoTabs.node = node
      this.switchNodeInfoTab({ name: this.nodeInfoTabs.activeTabName })
    },
    switchNodeInfoTab(tab, event) {
      this.nodeInfoTabs.activeTabName = tab.name

      switch (tab.name) {
        case 'clients':
          redis.clients(this.connParam, this.nodeInfoTabs.nodeId).then(res => {
            this.nodeInfoTabs.clients.data = res.data
          })
          break
        case 'memory':
          redis.memory(this.connParam, this.nodeInfoTabs.nodeId).then(res => {
            this.nodeInfoTabs.memory.data = res.data
          })
          break
        case 'slowlogs':
          redis.slowlogs(this.connParam, this.nodeInfoTabs.nodeId).then(res => {
            this.nodeInfoTabs.slowlogs.data = res.data
          })
          break
        case 'dbSize':
          // console.log(this.nodeInfoTabs,'node')
          if (this.nodeInfoTabs.node){
            let dbSizes = this.nodeInfoTabs.node.dbSizes
            this.nodeInfoTabs.dbSize.data = []
            for (let key in dbSizes){
              this.nodeInfoTabs.dbSize.data.push({db: key,size: dbSizes[key]})
            }
          }
          break
        case 'server':
          redis.server(this.connParam,this.nodeInfoTabs.nodeId).then(res => {
            this.nodeInfoTabs.server.data = res.data
          })
          break
      }
    },
    loadRedisConnInfo() {
      redis.connInfo(this.connParam).then(res => {
        Object.assign(this.connInfo, res.data)
        this.$emit('onConnInfoChange', this.connInfo)
      })
    },
    killClient(client, nodeId) {
      redis.killClient(this.connParam, client, nodeId)
      this.switchNodeInfoTab({ name: 'clients' })
    },
    handleNodeInfoTabSizeChange(val) {
      switch (this.nodeInfoTabs.activeTabName) {
        case 'clients':
          this.nodeInfoTabs.clients.input.pageSize = val
          break
        case 'slowlogs':
          this.nodeInfoTabs.slowlogs.input.pageSize = val
      }
    },
    handleNodeInfoTabCurrentChange(val) {
      switch (this.nodeInfoTabs.activeTabName) {
        case 'clients':
          this.nodeInfoTabs.clients.input.currentPage = val
          break
        case 'slowlogs':
          this.nodeInfoTabs.slowlogs.input.currentPage = val
      }
    }
  },
  watch: {
    'connInfo.masterNodes': {
      handler(val){
        if (val && val.length > 0){
          this.$nextTick(() => {
            document.querySelector('.el-tree-node__content').click()
          })
        }
      }
    }
  }
}
</script>

<style scoped>
.custom-tree-node{
  display: flex;
  align-items: center;
  width: 100%;
}
.custom-tree-node>button{
  margin-left: auto;
}
.memory-show{
  list-style-type: none;font-size: 15px;line-height: 2;
}
.memory-show li>label{
  display: inline-block;
  text-align: right;
  width: 80px;
}
</style>
